/**
 ********************************************************************
 * @author roocket
 * @file    curl.h
 * @version V0.0.0
 * @date    2024/3/22
 * @brief   This file is to indicate curl functions. 
 * @attention Code file rules:
 * rule: file encoding use UTF8;
 * rule: max line length 120 characters;
 * rule: line separator \r\n;
 * rule: use clion auto code format tool.
 */
#ifndef _CURL_H_
#define _CURL_H_

#include <stdio.h>
#include <curl/curl.h>
#include <stdbool.h>
#include <pthread.h>
#include <stdlib.h>

#define USE_MMAP (0)

/* structure for mmap */
#if USE_MMAP
#define MMAP_BUFFER_SIZE (128 * 1024)
struct curl_download_st
{
    size_t package_offset;
    size_t buffer_left;
    int mmap_id;
    int mmap_file;
    int curl_buffer_size;
    unsigned char *curl_buffer;
};
#endif

#define CURL_FILE_NAME_LEN_MAXIMUM 256
#define CURL_SPEED_1K_BYTE 1024

/* http code */
#define HTTP_RSP_CODE_400 400
#define HTTP_RSP_CODE_200 200

struct curl_user_hdl
{
    /* The progress bar of curl's downloading or uploading files */
    size_t (*curl_get_progress_bar)(void *p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);

    /* The spent time it used */
    void (*curl_get_spent_time)(const char *ptheads, struct timeval *start, struct timeval *finish);

    /* the curl_file_location of file */
    const char curl_file_location[CURL_FILE_NAME_LEN_MAXIMUM];

#if 1 // @fixme
    /* whether it is a breaking point */
    bool curl_is_break_point;

    /* the breaking point resumption for position */
    long curl_break_point;
#endif 
    /* limit speed */
    unsigned int curl_limit_speed_kb;

    /* timeout of curl's performing */
    unsigned short curl_timeout;

    /* whether if multiple or not */
    bool curl_is_multiple;

    /* file size */
    unsigned int file_size;
};

struct _ranges_download
{
    const char *url;
    const char *range;
    struct curl_user_hdl *curl;
    char *location;
};

/**
 * @brief Get the file from server or other service like cloud by downloading.
 * @note The url is specific for its remote address.
 * @param url The address of website.
 * @param cl_user The user for curl handler.
 * @return.
 */
int curl_download_file(const char *url, struct curl_user_hdl *cl_user);

/**
 * @brief Set the file from server or other service like cloud by uploading.
 * @note The url is specific for its remote address.
 * @param url The address of website.
 * @param cl_user The user for curl handler.
 * @return.
 */
int curl_upload_file(const char *url, struct curl_user_hdl *cl_user);

/**
 * @brief Get the size of http's file.
 * @note Use curl's inner APIs to get size.
 * @param url The address of website.
 * @return <long int> The size of file.
*/
long int curl_get_url_file_size(const char *url);

/**
 * @brief Get the md5 for making well the completely file.
 * @param url The address of website.
 * @return <string> The md5 of file.
*/
char *curl_get_md5_of_file(const char *url);

#endif /* _CURL_H_ */